package com.he.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.he.constant.RedisConstant;
import com.he.domain.dto.CategoryDTO;
import com.he.domain.dto.ConditionDTO;
import com.he.domain.dto.PageResult;
import com.he.domain.vo.*;
import com.he.entity.Article;
import com.he.entity.Category;
import com.he.mapper.ArticleMapper;
import com.he.mapper.CategoryMapper;
import com.he.service.CategoryService;
import com.he.service.RedisService;
import com.he.utils.BeanCopyUtils;
import com.he.utils.PageUtils;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author He
 * @version 1.0
 * @Date 2023/9/17 17:03
 * @Desc 分类数量Service实现类
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private ArticleMapper articleMapper;

    @Resource
    private RedisService redisService;

    @Override
    public List<CategoryVO> listCategoryVO() {
        return categoryMapper.getCategoryVOList();
    }

    @Override
    public ArticleConditionList listCategoryArticleVO(ConditionDTO conditionDTO) {
        if(conditionDTO.getCategoryId() == null){
            return ArticleConditionList.builder()
                    .articleConditionVOList(Collections.emptyList())
                    .name("")
                    .build();
        }
        // redis获取分类下的文章信息
        List<ArticleConditionVO> articleConditionVOS = redisService.getHash(RedisConstant.CATEGORY_ARTICLE_LIST,
                conditionDTO.getCategoryId().toString());
        if(Objects.isNull(articleConditionVOS)){
            // mysql获取分类下的文章信息
            articleConditionVOS = articleMapper.listArticleByCondition(PageUtils.getLimit(), PageUtils.getSize(), conditionDTO);
            //设置浏览量
            articleConditionVOS = articleConditionVOS.stream().map(
                    articleConditionVO -> {
                        Double articleViewCount = redisService.getZsetScore(RedisConstant.ARTICLE_VIEW_COUNT, articleConditionVO.getId());
                        articleConditionVO.setArticleViews(articleViewCount == null ? 0 : articleViewCount.intValue());
                        return articleConditionVO;
                    }
            ).collect(Collectors.toList());
            // redis存储分类下的文章信息
            redisService.setHash(RedisConstant.CATEGORY_ARTICLE_LIST, conditionDTO.getCategoryId().toString(), articleConditionVOS);
        }else {
            //设置浏览量
            articleConditionVOS = articleConditionVOS.stream().map(
                    articleConditionVO -> {
                        Double articleViewCount = redisService.getZsetScore(RedisConstant.ARTICLE_VIEW_COUNT, articleConditionVO.getId());
                        articleConditionVO.setArticleViews(articleViewCount == null ? 0 : articleViewCount.intValue());
                        return articleConditionVO;
                    }
            ).collect(Collectors.toList());
        }
        return ArticleConditionList.builder()
                .articleConditionVOList(articleConditionVOS)
                .name("")
                .build();
    }

    @Override
    public List<CategoryOptionVO> listCategoryOption() {
        // 查询分类
        List<Category> categoryList = categoryMapper.selectList(new LambdaQueryWrapper<Category>()
                .orderByDesc(Category::getId));
        return BeanCopyUtils.copyBeanList(categoryList, CategoryOptionVO.class);
    }

    @Override
    public PageResult<CategoryBackVO> listCategoryBackVO(ConditionDTO condition) {
        // 查询分类数量
        Long count = categoryMapper.selectCount(new LambdaQueryWrapper<Category>()
                .like(StringUtils.hasText(condition.getKeyword()), Category::getCategoryName,
                        condition.getKeyword()));
        if (count == 0) {
            return new PageResult<>();
        }
        // 分页查询分类列表
        List<CategoryBackVO> categoryList = categoryMapper.selectCategoryBackVO(PageUtils.getLimit(),
                PageUtils.getSize(), condition.getKeyword());
        return new PageResult<>(categoryList, count);
    }

    @Override
    public void addCategory(CategoryDTO category) {
        // 分类是否存在
        Category existCategory = categoryMapper.selectOne(new LambdaQueryWrapper<Category>()
                .select(Category::getId)
                .eq(Category::getCategoryName, category.getCategoryName().trim()));
        Assert.isNull(existCategory, category.getCategoryName().trim() + "分类已存在");
        // 添加新分类
        Category newCategory = Category.builder()
                .categoryName(category.getCategoryName())
                .build();
        baseMapper.insert(newCategory);
    }

    @Override
    public void deleteCategory(List<Integer> categoryIdList) {
        // 分类下是否有文章
        Long count = articleMapper.selectCount(new LambdaQueryWrapper<Article>()
                .in(Article::getCategoryId, categoryIdList));
        Assert.isFalse(count > 0, "删除失败，分类下存在文章");
        // 批量删除分类
        categoryMapper.deleteBatchIds(categoryIdList);
    }

    @Override
    public void updateCategory(CategoryDTO category) {
        // 分类是否存在
        Category existCategory = categoryMapper.selectOne(new LambdaQueryWrapper<Category>()
                .select(Category::getId)
                .eq(Category::getCategoryName, category.getCategoryName().trim()));
        Assert.isFalse(Objects.nonNull(existCategory) && !existCategory.getId().equals(category.getId()),
                category.getCategoryName().trim() + "分类已存在");
        // 修改分类
        Category newCategory = Category.builder()
                .id(category.getId())
                .categoryName(category.getCategoryName())
                .build();
        baseMapper.updateById(newCategory);
    }
}
